﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ApiServer.AppOotions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Logging;
using KJFrame.Core.Log;
using DotNetCore.CAP;
using System.Data.SqlClient;
using Dapper;
using Newtonsoft.Json;

namespace ApiServer.Controllers
{
    /// <summary>
    /// 所有测试
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class AllDemo1Controller : ControllerBase
    {

        /// <summary>
        /// 配置
        /// </summary>
        private readonly IConfiguration _configuration;

        /// <summary>
        /// 缓存配置
        /// </summary>
        private readonly CachedOptions _options;

        /// <summary>
        /// 缓存配置
        /// </summary>
        private readonly ComplexOptions _complexOptions;

        /// <summary>
        /// 表配置
        /// </summary>
        private readonly TableOptions _tableOptions;

        /// <summary>
        /// 日志
        /// </summary>
        private readonly ILogger _logger;

        /// <summary>
        /// Capbus
        /// </summary>
        private readonly ICapPublisher _capBus;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="options"></param>
        /// <param name="complexOptions"></param>
        /// <param name="tableOptions"></param>
        /// <param name="logger"></param>
        /// <param name="capPublisher"></param>
        public AllDemo1Controller(IConfiguration configuration,
            IOptions<CachedOptions> options,
            IOptionsSnapshot<ComplexOptions> complexOptions,
            IOptionsMonitor<TableOptions> tableOptions,
            ILogger logger,
            ICapPublisher capPublisher)
        {
            _configuration = configuration;
            //读取一次的IOptions配置
            _options = options.Value;
            _logger = logger;
            _capBus = capPublisher;
            _complexOptions = complexOptions.Value;
            _tableOptions = tableOptions.CurrentValue;

            //监控配置的回调测试
            tableOptions.OnChange((temp, info) =>
            {
                Console.WriteLine(JsonConvert.SerializeObject(temp));
            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public string Index()
        {
            return "hello word";
        }

        /// <summary>
        /// apollo获取配置字符串
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> DemoApolloString()
        {
            var capConnection = _configuration.GetSection("CapConection")?.Value;
            return capConnection;
        }

        /// <summary>
        /// IOptions读取Apollo
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<CachedOptions> DemoApolloIOptions()
        {
            return _options;
        }

        /// <summary>
        /// IOptionsSnapshot读取Apollo
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<ComplexOptions> DemoApolloIOptionsSnapshot()
        {
            return _complexOptions;
        }

        /// <summary>
        ///IOptionsMonitor读取Apollo
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<TableOptions> DemoApolloIOptionsMonitor()
        {
            return _tableOptions;
        }

        /// <summary>
        /// 日志测试
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> DemoLog()
        {
            _logger.LogTrace(1, "首页日志", "首页日志信息", this.GetType().FullName, "Index");
            _logger.LogKJDebug(1, "首页日志", "首页日志信息", this.GetType().FullName, "Index");
            _logger.LogKJInformation(1, "首页日志", "首页日志信息", this.GetType().FullName, "Index");
            _logger.LogKJWarning(1, "首页日志", "首页日志信息", this.GetType().FullName, "Index");
            _logger.LogKJError(1, "首页日志", "首页日志信息", this.GetType().FullName, "Index");
            _logger.LogKJCritical(1, "首页日志", "首页日志信息", this.GetType().FullName, "Index");
            return "hello word log writed";
        }

        /// <summary>
        /// 简单消息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> DemoPublish()
        {
            await _capBus.PublishAsync("kjframe.test", DateTime.Now);
            return Content("Hello word");
        }

        /// <summary>
        /// 手动提交事务
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> DemoTransaction()
        {
            using (var connnection = new SqlConnection("Integrated Security=False;server=192.168.1.109;database=cap;User ID=sa;Password=198603yang;Connect Timeout=30"))
            {
                using (var transaction = connnection.BeginTransaction(_capBus, false))
                {
                    var sql = "update UserTransaction set Name='嘻嘻' where id=1";
                    connnection.Execute(sql, null, transaction);
                    await _capBus.PublishAsync("kjframe.test", DateTime.Now);
                    transaction.Commit();
                    return Content("服务端send");
                }
            }
        }

        /// <summary>
        /// 自动提交事务
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> DemoTransactionAuto()
        {
            using (var connnection = new SqlConnection("Integrated Security=False;server=192.168.1.109;database=cap;User ID=sa;Password=198603yang;Connect Timeout=30"))
            {
                using (var transaction = connnection.BeginTransaction(_capBus, true))
                {
                    var sql = "update UserTransaction set Name='hahahah' where id=1";
                    connnection.Execute(sql, null, transaction);
                    await _capBus.PublishAsync("kjframe.test", DateTime.Now);
                    return Content("服务端send");
                }
            }
        }

        /// <summary>
        /// 服务端：带callbackName参数的推送
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> DemoPublishCallback()
        {
            await _capBus.PublishAsync("kjframe.test", DateTime.Now, "IServerCall");
            return Content("服务端这个推送了一个包含callbackName=IServerCall的消息");
        }
    }
}